/**
 * Stats
 *
 * Released under MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * How to use:
 *
 *	addChild( new Stats() );
 *
 *	or
 *
 *	addChild( new Stats( { bg: 0xffffff } );
 *
 * version log:
 *
 *	09.10.22		2.2		Mr.doob			+ FlipX of graph to be more logic.
 *											+ Destroy on Event.REMOVED_FROM_STAGE (thx joshtynjala)
 *	09.03.28		2.1		Mr.doob			+ Theme support.
 *	09.02.21		2.0		Mr.doob			+ Removed Player version, until I know if it's really needed.
 *											+ Added MAX value (shows Max memory used, useful to spot memory leaks)
 *											+ Reworked text system / no memory leak (original reason unknown)
 *											+ Simplified
 *	09.02.07		1.5		Mr.doob			+ onRemovedFromStage() (thx huihuicn.xu)
 *	08.12.14		1.4		Mr.doob			+ Code optimisations and version info on MOUSE_OVER
 *	08.07.12		1.3		Mr.doob			+ Some speed and code optimisations
 *	08.02.15		1.2		Mr.doob			+ Class renamed to Stats (previously FPS)
 *	08.01.05		1.2		Mr.doob			+ Click changes the fps of flash (half up increases, half down decreases)
 *	08.01.04		1.1		Mr.doob			+ Shameless ripoff of Alternativa's FPS look :P
 *							Theo			+ Log shape for MEM
 *											+ More room for MS
 * 	07.12.13		1.0		Mr.doob			+ First version
 **/
package org.zengrong.utils {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.system.System;
	import flash.text.StyleSheet;
	import flash.text.TextField;
	import flash.utils.getTimer;

	public class Stats extends Sprite {
		protected var WIDTH:uint = 70;
		protected var HEIGHT:uint = 100;
		protected var xml:XML;
		protected var text:TextField;
		protected var style:StyleSheet;
		protected var timer:uint;
		protected var fps:uint;
		protected var ms:uint;
		protected var ms_prev:uint;
		protected var mem:Number;
		protected var mem_max:Number;
		protected var graph:Bitmap;
		protected var rectangle:Rectangle;
		protected var fps_graph:uint;
		protected var mem_graph:uint;
		protected var mem_max_graph:uint;
		protected var theme:Object = {bg: 0x000033, fps: 0xffff00, ms: 0x00ff00, mem: 0x00ffff, memmax: 0xff0070};
		//是否显示背景色
		private var _showBackground:Boolean;
		//是否显示轨迹
		private var _showFooter:Boolean;

		/**
		 * <b>Stats</b> FPS, MS and MEM, all in one.
		 *
		 * @param _theme         Example: { bg: 0x202020, fps: 0xC0C0C0, ms: 0x505050, mem: 0x707070, memmax: 0xA0A0A0 }
		 */
		public function Stats(_theme:Object = null, $showBackground:Boolean = true, $showFooter:Boolean = true, $width:int = 70, $height:int = 100):void {
			if (_theme){
				if (_theme.bg != null)
					theme.bg = _theme.bg;
				if (_theme.fps != null)
					theme.fps = _theme.fps;
				if (_theme.ms != null)
					theme.ms = _theme.ms;
				if (_theme.mem != null)
					theme.mem = _theme.mem;
				if (_theme.memmax != null)
					theme.memmax = _theme.memmax;
			}
			_showBackground = $showBackground;
			_showFooter = $showFooter;
			WIDTH = $width;
			HEIGHT = $height;
			mem_max = 0;
			xml =  <xml><fps>FPS:</fps><ms>MS:</ms><mem>MEM:</mem><memMax>MAX:</memMax></xml>;

			style = new StyleSheet();
			style.setStyle("xml", {fontSize: '9px', fontFamily: '_sans', leading: '-2px'});
			style.setStyle("fps", {color: hex2css(theme.fps)});
			style.setStyle("ms", {color: hex2css(theme.ms)});
			style.setStyle("mem", {color: hex2css(theme.mem)});
			style.setStyle("memMax", {color: hex2css(theme.memmax)});
			text = new TextField();
			text.width = WIDTH;
			text.height = 50;
			text.styleSheet = style;
			text.condenseWhite = true;
			text.selectable = false;
			text.mouseEnabled = false;
			if (_showFooter){
				graph = new Bitmap();
				graph.y = 50;
			}
			rectangle = new Rectangle(WIDTH - 1, 0, 1, HEIGHT - 50);
			addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
			addEventListener(Event.REMOVED_FROM_STAGE, destroy, false, 0, true);
		}

		private function init(e:Event):void {
			if (_showBackground){
				graphics.beginFill(theme.bg);
				graphics.drawRect(0, 0, WIDTH, HEIGHT);
				graphics.endFill();
			}
			addChild(text);
			if (_showFooter){
				graph.bitmapData = new BitmapData(WIDTH, HEIGHT - 50, false, theme.bg);
				addChild(graph);
			}
			addEventListener(MouseEvent.CLICK, onClick);
			addEventListener(Event.ENTER_FRAME, update);
		}

		private function destroy(e:Event):void {
			graphics.clear();
			while (numChildren > 0)
				removeChildAt(0);
			if (_showFooter){
				graph.bitmapData.dispose();
			}
			removeEventListener(MouseEvent.CLICK, onClick);
			removeEventListener(Event.ENTER_FRAME, update);
		}

		private function update(e:Event):void {
			timer = getTimer();
			if (timer - 1000 > ms_prev){
				ms_prev = timer;
				mem = Number((System.totalMemory * 0.000000954).toFixed(3));
				mem_max = mem_max > mem ? mem_max : mem;
				if (_showFooter){
					fps_graph = Math.min(graph.height, (fps / stage.frameRate) * graph.height);
					mem_graph = Math.min(graph.height, Math.sqrt(Math.sqrt(mem * 5000))) - 2;
					mem_max_graph = Math.min(graph.height, Math.sqrt(Math.sqrt(mem_max * 5000))) - 2;
					graph.bitmapData.scroll(-1, 0);
					graph.bitmapData.fillRect(rectangle, theme.bg);
					graph.bitmapData.setPixel(graph.width - 1, graph.height - fps_graph, theme.fps);
					graph.bitmapData.setPixel(graph.width - 1, graph.height - ((timer - ms) >> 1), theme.ms);
					graph.bitmapData.setPixel(graph.width - 1, graph.height - mem_graph, theme.mem);
					graph.bitmapData.setPixel(graph.width - 1, graph.height - mem_max_graph, theme.memmax);
				}
				xml.fps = "FPS: " + fps + " / " + stage.frameRate;
				xml.mem = "MEM: " + mem;
				xml.memMax = "MAX: " + mem_max;
				fps = 0;
			}
			fps++;
			xml.ms = "MS: " + (timer - ms);
			ms = timer;
			text.htmlText = xml;
		}

		private function onClick(e:MouseEvent):void {
			mouseY / height > .5 ? stage.frameRate-- : stage.frameRate++;
			xml.fps = "FPS: " + fps + " / " + stage.frameRate;
			text.htmlText = xml;
		}

		// .. Utils
		private function hex2css(color:int):String {
			return "#" + color.toString(16);
		}
	}
}